home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: uniq.c
- * Author: Oliver Kaufmann
- *
- * created: ?
- * last modified: 10.6.1994
- * Version: $VER: uniq 1.1
- *
- * Doc: uniq.doc
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos/dos.h>
- #include <functions.h>
- #include <string.h>
-
- void CloseAll(char *s);
- char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer);
- char *modifyname(char *tb, int blen, int elen, long sernum, int origlen);
- char *savestring(char *s);
- struct tbl *feedtbl(char *s, struct tbl *firsttbl, int type);
- struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl);
- struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl);
- struct tbl *inserttbl(char *s, char *t, int type, struct tbl *firsttbl);
- struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen);
- struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen);
- void uniqthislevel(struct tbl *thisdir, char *origpathname, char *newpathname);
- void giveout(struct tbl *firsttbl, char *lformat, int allflag, int quoteflag);
- struct tbl *freetbl(struct tbl *thistbl);
-
-
- char ver[] = "$VER: uniq 1.1 (10.6.1994) © by Oliver Kaufmann";
- char *usage = "uniq [<options>]\n\
- -d[<dir>] : use contents of <dir> as input, otherwise use stdin\n\
- -a : print all names, even those which do not change\n\
- -f : process files only, no dirs (requires -d option)\n\
- -q : enclose output in quotes (rename \"%s\" \"%s\")\n\
- -r : recurse sub-dirs (requires -d option)\n\
- -l<lformat> : use <lformat> for output (default rename %s %s)\n\
- -m[<mformat>] : enable & print <mformat> for dirs (default makedir %s)\n\
- -p<pattern> : pattern to apply (default #?)\n\
- -b<basenamelength> : max. length of the uniqified string (default 8)\n\
- -e<extensionlength> : max. length of the uniqified extension (default 3)";
-
-
- struct tbl {
- char *orig;
- char *new;
- int type;
- struct tbl *nexttbl;
- };
-
- struct MyAnchorPath {
- struct AChain *ap_Base; /* pointer to first anchor */
- struct AChain *ap_Last; /* pointer to last anchor */
- LONG ap_BreakBits; /* Bits we want to break on */
- LONG ap_FoundBreak; /* Bits we broke on. Also returns ERROR_BREAK */
- BYTE ap_Flags; /* New use for extra word. */
- BYTE ap_Reserved;
- WORD ap_Strlen; /* This is what ap_Length used to be */
- struct FileInfoBlock ap_Info;
- UBYTE ap_Buf[1]; /* Buffer for path name, allocated by user */
- };
-
-
- #define BUFLEN 256
- char pbuf[BUFLEN];
- char str1[BUFLEN];
- char str2[BUFLEN];
-
- int level = 0;
- int quoteflag = 0;
- int mformflag = 0;
- int allfilendirs = 1;
- int allflag = 0;
- int recursflag = 0;
- int blen=8;
- int elen=3;
- char *lformat = "rename %s %s";
- char *mformat = "makedir %s";
- char *pattern="#?";
-
- void main(int argc, char *argv[])
- {
- struct tbl localtbl;
- struct tbl *firsttbl=NULL;
- char lbuf[BUFLEN];
- char *dirname=NULL;
-
- char *s, *opt;
- int i, res;
-
- for(i=1; i<argc; i++) {
- if( *(opt=argv[i]) == '-') {
- switch(opt[1]) {
- case 'd' : dirname = &opt[2]; break;
- case 'a' : allflag = 1 ; break;
- case 'r' : recursflag = 1 ; break;
- case 'q' : quoteflag = 1 ; break;
- case 'f' : allfilendirs = 0 ; break;
- case 'l' : lformat = &opt[2]; break;
- case 'p' : pattern = &opt[2]; break;
- case 'm' : mformflag = 1;
- if( opt[2] != 0 )
- mformat = &opt[2];
- break;
- case 'b' : if( (blen = atoi(&opt[2]) ) <= 0)
- CloseAll("basenamelength must be > 0");
- break;
- case 'e' : if( (elen = atoi(&opt[2])) < 0)
- CloseAll("extensionlength must be >= 0");
- break;
- default : printf("unknown option: ignored\n");
- break;
- }
- } else if( *opt == '?')
- CloseAll(usage);
- }
-
- if(dirname != NULL) {
- localtbl.orig = dirname;
- localtbl.new = "";
- localtbl.nexttbl = NULL;
- uniqthislevel(&localtbl,dirname,"");
- } else {
- if( ParsePattern(pattern, pbuf, BUFLEN) == -1)
- CloseAll("pattern too long");
- while( (res=scanf("%s",lbuf)) != EOF) {
- if(res==0)
- CloseAll("res = 0");
- if(MatchPattern(pbuf, lbuf)) /* nur wenn pattern matched */
- firsttbl = feedtbl(lbuf, firsttbl, 0);
- }
- if(firsttbl != NULL)
- if( (firsttbl=makeuniq(firsttbl, blen, elen)) == NULL)
- CloseAll("unable to uniqify filetbl");
- giveout(firsttbl, lformat, allflag, quoteflag);
- }
-
- CloseAll(NULL);
- }
-
- #define PATHNAMELEN 256
- void uniqthislevel(struct tbl *thisdir, char *origpathname, char *newpathname)
- {
- struct FileInfoBlock *fib;
- struct AnchorPath *ap;
- int result, emptyflag = 1;
- char origpath[PATHNAMELEN]; /* store full orig path */
- char newpath[PATHNAMELEN]; /* store full new path */
- struct tbl *looptbl=NULL;
- struct tbl *firsttbl=NULL;
- BPTR lock, oldlock;
-
- if(thisdir == NULL) {
- return;
- }
-
- level += 1;
-
- if( (ap=(struct AnchorPath *)malloc(sizeof(struct MyAnchorPath)) ) == NULL)
- CloseAll("no memory for MyAnchorPath");
-
- memset(ap,0,sizeof(struct MyAnchorPath)-1); /* crucial ! struct must be 0ed */
- /* took me 2 h to find out */
- if( (lock=Lock(thisdir->orig,ACCESS_READ)) == 0)
- CloseAll("no lock on dir");
- oldlock = CurrentDir(lock);
-
- ap->ap_Strlen = 0;
- ap->ap_BreakBits = 0;
- ap->ap_FoundBreak = 0;
-
- result = MatchFirst(pattern, ap); /* pattern global ! */
- if ( result == 0 ) {
- do {
- emptyflag = 0;
- fib = &ap->ap_Info;
- firsttbl = feedtbl(fib->fib_FileName, firsttbl, fib->fib_DirEntryType);
- } while ( !(result = MatchNext(ap)) );
- }
-
- if(result != ERROR_NO_MORE_ENTRIES)
- CloseAll("MatchFirst: other error");
-
- MatchEnd(ap);
- free(ap);
-
- if(firsttbl != NULL) {
- if( (firsttbl=makeuniq(firsttbl, blen, elen)) == NULL)
- CloseAll("unable to uniqify filetbl");
- }
-
- looptbl = firsttbl;
- while (looptbl != NULL) {
- strcpy(origpath,origpathname);
- if( !AddPart(origpath, looptbl->orig, PATHNAMELEN) )
- CloseAll("path to long");
- strcpy(newpath, newpathname);
- if( !AddPart(newpath, looptbl->new, PATHNAMELEN) )
- CloseAll("path to long");
-
- if(mformflag && looptbl->type >= 0) { /* directory special output */
- *str1 = 0;
- if(quoteflag) strcat(str1,"\"");
- strcat(str1,newpath);
- if(quoteflag) strcat(str1,"\"");
- printf(mformat, str1);
- printf("\n");
- }
- if( allfilendirs || looptbl->type < 0) { /* file output */
- if( allflag || strcmp(looptbl->orig, looptbl->new) ) {
- *str1 = 0;
- if(quoteflag) strcat(str1,"\"");
- strcat(str1,origpath);
- if(quoteflag) strcat(str1,"\"");
- *str2 = 0;
- if(quoteflag) strcat(str2,"\"");
- strcat(str2,newpath);
- if(quoteflag) strcat(str2,"\"");
- printf(lformat ,str1, str2);
- printf("\n");
- }
- }
- if(recursflag && looptbl->type >= 0) {
- uniqthislevel(looptbl, origpath, newpath);
- }
-
- looptbl = looptbl->nexttbl;
- }
-
- CurrentDir(oldlock);
- UnLock(lock);
- freetbl(firsttbl); /* free memory */
- level -= 1;
- }
-
-
-
- struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen)
- {
- struct tbl *thistbl;
-
- thistbl = firsttbl;
- while(thistbl != NULL) {
- if( uniq(thistbl, firsttbl, blen, elen) == NULL)
- return NULL;
- thistbl = thistbl->nexttbl;
- }
- return firsttbl;
- }
-
- struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen)
- {
- char lbuf[BUFLEN];
- char buffer[BUFLEN];
-
- char *t, *tb, *tex;
- char *s;
-
- long sernum;
- int origlen;
-
- s = thistbl->orig;
- makename(s, blen, elen, &tb, &tex, buffer); /* name und extension */
- origlen = strlen(tb); /* base name length */
-
- for(sernum = 0; ; sernum++) {
- strcpy(lbuf,tb);
- strcat(lbuf,tex);
- if( lookup(lbuf, firsttbl, thistbl) == NULL )
- break;
- if( modifyname(tb, blen, elen, sernum, origlen) == 0)
- return NULL;
- }
-
- t = savestring(lbuf);
-
- modifytbl(s, t, thistbl);
-
- return thistbl;
- }
-
- struct tbl *inserttbl(char *s, char *t, int type, struct tbl *firsttbl)
- {
- struct tbl *thistbl;
-
- if( (thistbl=malloc(sizeof(struct tbl))) == NULL)
- CloseAll("no memory for tbl");
-
- thistbl->type = type;
- thistbl->orig = s;
- thistbl->new = t;
- thistbl->nexttbl = firsttbl;
- return thistbl;
-
- }
-
- struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl)
- {
- thistbl->orig = s;
- thistbl->new = t;
- return thistbl;
- }
-
- struct tbl *feedtbl(char *s, struct tbl *firsttbl, int type)
- {
- char *m;
-
- m = savestring(s);
- return inserttbl(m, m, type, firsttbl);
- }
-
- char *savestring(char *s)
- {
- char *mem;
-
- if( (mem=malloc(strlen(s)+1)) == NULL)
- CloseAll("no memory for string");
-
- strcpy(mem, s);
- return mem;
- }
-
- struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl)
- {
- while(firsttbl != NULL) {
- if( (strcmp(t, firsttbl->new) == 0) && (firsttbl != excludetbl) )
- break;
- firsttbl = firsttbl->nexttbl;
- }
- return firsttbl;
- }
-
-
- char *modifyname(char *tb, int blen, int elen, long sernum, int origlen)
- {
- char lbuf[BUFLEN];
- int sl, i, j, pos;
-
- sprintf(lbuf,"%x",sernum);
- if( (sl = strlen(lbuf)) > blen ) /* sernum zu groß */
- return NULL;
-
- pos = origlen;
- if( origlen + sl > blen )
- pos = blen-sl;
- strncpy(tb+pos, lbuf, sl);
- return tb;
- }
-
- char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer)
- {
- char *t;
- int n,m;
- int sl,i;
-
- *tb = buffer;
-
- for(n=0, t=s ; (*t != '\0') && (*t != '.') ; *t++, n++);
-
- strncpy(buffer, s, n); /* es wird evtl mehr kopiert */
-
- while(n<blen)
- buffer[n++] = '\0'; /* auffüllen */
-
- buffer[blen] = '\0'; /* rest abschneiden */
-
- n = blen+1; /* ab hier extension */
-
- buffer[n] = '\0'; /* default ist leer */
-
- *tex = &buffer[n];
-
- if(elen != 0 ) {
-
- for(i = sl = strlen(s)-1; sl >= 0; sl--)
- if(s[sl] == '.')
- break;
- if(s[sl] == '.') {
- buffer[n++] = '.';
- strncpy(&buffer[n], &s[sl+1], i-sl+1); /* 0 mitkopieren */
- n += i-sl;
- }
-
- buffer[n] = '\0'; /* default ist leer */
- buffer[blen+elen+1+1]='\0';
-
- }
-
- return *tb;
-
- }
-
- void giveout(struct tbl *firsttbl, char *lformat, int allflag, int quoteflag)
- {
- while (firsttbl != NULL) {
- if( allflag || strcmp(firsttbl->orig, firsttbl->new) ) {
- *str1 = 0;
- if(quoteflag) strcat(str1,"\"");
- strcat(str1,firsttbl->orig);
- if(quoteflag) strcat(str1,"\"");
- *str2 = 0;
- if(quoteflag) strcat(str2,"\"");
- strcat(str2,firsttbl->new);
- if(quoteflag) strcat(str2,"\"");
- printf(lformat, str1, str2);
- printf("\n");
- }
- firsttbl = firsttbl->nexttbl;
- }
- }
-
-
- struct tbl *freetbl(struct tbl *thistbl)
- {
- struct tbl *tmptbl;
-
- while(thistbl != NULL) {
- if(thistbl->orig != NULL)
- free(thistbl->orig);
- if( (thistbl->new != NULL) && (thistbl->new != thistbl->orig) )
- free(thistbl->new);
- tmptbl = thistbl;
- thistbl = thistbl->nexttbl;
- free(tmptbl);
- }
- return NULL;
- }
-
- void CloseAll(char *s)
- {
- if(s != NULL)
- printf("%s\n",s);
- exit(0);
- }
-